package game.module.item.logic;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import game.common.ErrorCodeConstants;
import game.common.ItemConstants;
import game.entity.PlayingRole;
import game.module.club.logic.ClubManager;
import game.module.dabt.logic.PayMoneyBack;
import game.module.item.bean.GainItemBean;
import game.module.item.bean.Item;
import game.module.item.dao.ItemCache;
import game.module.item.dao.ItemTemplateCache;
import game.module.user.logic.PlayerDaoHelper;
import game.session.SessionManager;
import lua.LuaMessageHall.Items;
import lua.LuaMessageHall.S2CPushpackItems;

public class ItemManager {

	private static Logger logger = LoggerFactory.getLogger(ItemManager.class);

	static class SingletonHolder {
		static ItemManager instance = new ItemManager();
	}

	public static ItemManager getInstance() {
		return SingletonHolder.instance;
	}

	public void addItem(PlayingRole playingRole, int itemTemplateId, int count, int playerId) {
		Item item = gainItemSigleByPlayerId(playingRole.getId(), itemTemplateId, count);
		// 执行道具改变推送
		if (item != null) {
			List<Item> pushItem = new ArrayList<Item>();
			pushItem.add(item);
			pushBagItems(playingRole, pushItem);
		}
	}

	/**
	 * 获取物品通用方法,自动推送物品的变化信息
	 * 
	 * @param playingRole
	 * @return
	 */
	public int gainItems(PlayingRole playingRole, List<GainItemBean> addList) {
		return gainItemsAndPush(playingRole.getId(), addList);
	}

	/**
	 * 获取对应的道具及在线推送
	 * 
	 * @param playerId
	 * @param addList
	 * @return
	 */
	public int gainItemsAndPush(int playerId, List<GainItemBean> addList) {
		if (addList == null || addList.isEmpty()) {
			return ErrorCodeConstants.SYS_REQ_PAR;
		}
		List<Item> pushItem = new ArrayList<Item>();
		Item item = null;
		for (GainItemBean gainItemBean : addList) {
			item = gainItemSigleByPlayerId(playerId, gainItemBean.getItemTemplateId(), gainItemBean.getCount());
			if (item != null) {
				pushItem.add(item);
			}
		}
		if (pushItem.size() <= 0) {
			return 1;
		}
		PlayingRole pr = SessionManager.getInstance().getPlayer(playerId);
		if (pr != null && pr.isChannelActive()) {
			pushBagItems(pr, pushItem);
		}
		return 1;
	}

	/**
	 * 获取指定物品
	 * 
	 * @param playerId
	 * @param itemId
	 * @param count
	 * @return
	 */
	public int gainItemsAndPush(int playerId, int itemId, int count) {
		List<GainItemBean> addList = new ArrayList<>();
		GainItemBean bean = new GainItemBean();
		bean.setCount(count);
		bean.setItemTemplateId(itemId);
		addList.add(bean);
		return gainItemsAndPush(playerId, addList);
	}

	/**
	 * 消耗指定物品 支持 离线扣除 房卡，积分，金豆； 支持在线扣除道具（离线不支持）
	 * 
	 * @param playerId
	 * @param itemId
	 * @param count
	 *            为正值
	 * @return
	 */
	public int reduceItemsAndPush(int playerId, int itemId, int count) {
		logger.info("reduceItemsAndPush ,playerId={},itemTemplateId={},count={},", playerId, itemId, count);
		if (count <= 0 || !checkTemplateExist(itemId)) {
			return ErrorCodeConstants.SYS_REQ_PAR;
		}
		ItemStatus itemStaus = preItemNumByPlayerId(playerId, itemId, -count);
		if (itemStaus.getErrorCode() != 1) {
			return itemStaus.getErrorCode();
		}
		List<Item> pushItem = new ArrayList<>();
		if (itemStaus.getItem() != null) {
			pushItem.add(itemStaus.getItem());
		}
		if (pushItem.size() <= 0) {
			return 1;
		}
		PlayingRole pr = SessionManager.getInstance().getPlayer(playerId);
		if (pr != null && itemId == ItemConstants.FANG_KA_ITEM_ID) {
			ClubManager.getInstance().expenseFangKaAddlivenessNum(pr, count);
		}
		if (pr != null && pr.isChannelActive()) {
			pushBagItems(pr, pushItem);
		}
		return 1;
	}

	/**
	 * 自动识别是增加还是扣除
	 * 
	 * @param playerId
	 * @param itemId
	 * @param count
	 * @return
	 */
	private ItemStatus preItemNumByPlayerId(int playerId, int itemId, int count) {
		logger.info("last act item,playerId={},itemTemplateId={},count={},", playerId, itemId, count);
		if (count == 0 || !checkTemplateExist(itemId)) {
			logger.error("fail act item,playerId={},itemId={},count={},or item not exist", playerId, itemId, count);
			return null;
		}
		Item item = new Item();
		item.setTemplateId(itemId);
		item.setCount(count);

		ItemStatus itemStatus = new ItemStatus();
		itemStatus.setErrorCode(1);

		PlayingRole pr = SessionManager.getInstance().getPlayer(playerId);
		switch (itemId) {
		case ItemConstants.FANG_KA_ITEM_ID:
			if (pr != null) {
				pr.getPlayerBean().setFang_ka(pr.getPlayerBean().getFang_ka() + count);
				item.setCount(pr.getPlayerBean().getFang_ka());
			}
			PlayerDaoHelper.getInstance().asyncAddFangKa(count, playerId);
			break;
		case ItemConstants.YUANBAO_ITEM_ID:// 金豆
			long newcout = PayMoneyBack.getInstance().payMoneybackonline(playerId, true, count);
			if (pr != null) {
				pr.getPlayerBean().setJin_dou(pr.getPlayerBean().getJin_dou() + newcout);
				Long jindou = pr.getPlayerBean().getJin_dou();
				item.setCount(jindou.intValue());
			}
			PlayerDaoHelper.getInstance().asyncAddJinDouForPlayerBean(playerId, newcout);
			break;
		case ItemConstants.COINS_ITEM_ID:
			if (pr != null) {
				pr.getPlayerBean().setCoins(pr.getPlayerBean().getCoins() + count);
				item.setCount(pr.getPlayerBean().getCoins());
			}
			PlayerDaoHelper.getInstance().asyncAddCoin(count, playerId);
			break;
		default:
			if (count < 0) {
				// 不支持离线 使用道具
				int errorCode = useItem(pr, itemId, -count);
				itemStatus.setErrorCode(errorCode);
				itemStatus.setItem(null);
				return itemStatus;
			} else {
				item = addBagShowItem(playerId, itemId, count);
			}
			break;
		}

		itemStatus.setItem(item);
		return itemStatus;
	}

	/**
	 * 获取物品包括所有货币
	 * 
	 * @param playerId
	 * @param itemTemplateId
	 * @param count
	 * @return
	 */
	private Item gainItemSigleByPlayerId(int playerId, int itemTemplateId, int count) {
		logger.info("add item,playerId={},itemTemplateId={},count={},", playerId, itemTemplateId, count);
		if (count <= 0 || !checkTemplateExist(itemTemplateId)) {
			logger.error("fail add item,playerId={},itemTemplateId={},count={},or item not exist", playerId, itemTemplateId, count);
			return null;
		}
		ItemStatus itemStatus = preItemNumByPlayerId(playerId, itemTemplateId, count);
		return itemStatus != null ? itemStatus.getItem() : null;
	}

	private Item addBagShowItem(int playerId, int itemTemplateId, int count) {
		Map<Integer, Item> itemMap = ItemCache.getInstance().getItemTemplateKey(playerId);
		// 道具已存在
		Item item = null;
		if (itemMap.containsKey(itemTemplateId)) {
			item = itemMap.get(itemTemplateId);
			item.setCount(item.getCount() + count);
			// save db
			boolean isUpdateTime = false;
			if (count > 0) {
				item.setUpdateTime(new Date());
				isUpdateTime = true;
			}
			ItemDaoHelper.getInstance().asyncUpdateItem(item.getTemplateId(), item.getCount(), item.getPlayerId(), isUpdateTime);
		} else {
			item = new Item();
			item.setPlayerId(playerId);
			item.setTemplateId(itemTemplateId);
			item.setCount(count);
			item.setUpdateTime(new Date());
			ItemCache.getInstance().addNew(playerId, item);
			// save db
			ItemDaoHelper.getInstance().asyncInsertItem(item);
		}

		return item;
	}

	public boolean checkTemplateExist(int itemTemplateId) {
		return ItemTemplateCache.getInstance().isTemplateExit(itemTemplateId);

	}

	/**
	 * 使用道具
	 * 
	 * @param playingRole
	 * @param itemTemplateId
	 * @param count
	 * @return -1 参数错误 112 道具不足 1.成功
	 */
	public int useItem(PlayingRole playingRole, int itemTemplateId, int count) {
		if (count <= 0 || playingRole == null) {
			return ErrorCodeConstants.SYS_REQ_PAR;
		}
		int playerId = playingRole.getId();
		Map<Integer, Item> itemMap = ItemCache.getInstance().getItemTemplateKey(playerId);
		if (itemMap == null || !itemMap.containsKey(itemTemplateId)) {
			return ErrorCodeConstants.HALL_NO_ITEM;
		}
		Item item = itemMap.get(itemTemplateId);
		if (item.getCount() < count) {
			return ErrorCodeConstants.HALL_NO_ITEM;
		}

		item.setCount(item.getCount() - count);
		item.setUpdateTime(new Date());
		if (item.getCount() <= 0) {
			itemMap.remove(itemTemplateId);
			ItemDaoHelper.asyncRemoveItem(itemTemplateId, playerId);
		} else {
			ItemDaoHelper.getInstance().asyncUpdateItem(item.getTemplateId(), item.getCount(), item.getPlayerId(), true);
		}

		List<Item> list = new ArrayList<>();
		list.add(item);
		pushBagItems(playingRole, list);
		return 1;
	}

	/**
	 * 推送制定道具的当前数量
	 * 
	 * @param playingRole
	 * @param list
	 */
	public void pushBagItems(PlayingRole playingRole, List<Item> list) {
		Items[] backpackItems = packItems(list);
		if (backpackItems == null) {
			return;
		}

		S2CPushpackItems respMsg = new S2CPushpackItems();
		respMsg.items = backpackItems; // 背包数据
		playingRole.writeAndFlush(respMsg.build(playingRole.alloc()));
	}

	/**
	 * 包装通用道具返回
	 * 
	 * @param list
	 * @return
	 */
	public Items[] packItems(List<Item> list) {
		if (list == null || list.size() <= 0) {
			return null;
		}
		List<Items> itemItems = new ArrayList<>();
		for (Item item : list) {
			Items itemsSig = new Items();
			itemsSig.item_id = item.getTemplateId();
			itemsSig.cnt = item.getCount();
			itemItems.add(itemsSig);
		}
		return itemItems.toArray(new Items[0]);
	}

	class ItemStatus {
		private Item item;
		private Integer errorCode;

		public Item getItem() {
			return item;
		}

		public void setItem(Item item) {
			this.item = item;
		}

		public Integer getErrorCode() {
			return errorCode;
		}

		public void setErrorCode(Integer errorCode) {
			this.errorCode = errorCode;
		}
	}
}
